#include <sys/types.h>
#include <iostream>

using std::cout;
using std::endl;

#include <unistd.h>
#include <sys/socket.h>
#include "SocketIO.h"
SocketIO::SocketIO(int fd)
: _fd(fd)
{

}

SocketIO::~SocketIO()
{
}

size_t SocketIO::readn(char* buf, size_t len)
{
    size_t left = len;
    char* pstr = buf;
    int read_count = 0;
    while(left > 0)
    {
        read_count = ::read(_fd, pstr, left);
        if(read_count == -1 && errno == EINTR)//可接受错误(中断)
        {
            continue;
        }
        else if(read_count == -1)//不可接受错误
        {
            perror("read");
            return -1;
        }
        else if(read_count == 0)//无可读数据
        {
            break;
        }
        else//正常读
        {
            pstr += read_count;
            left -= read_count;
        }
    }

    return len - left;
}

size_t SocketIO::writen(const char* buf, size_t len)
{
    const char* pstr = buf;
    size_t left = len;
    int ret = 0;
    while(left > 0)
    {
        ret = ::write(_fd, pstr, left);
        if(ret == -1 && errno == EINTR)
        {
            continue;
        }
        else if(ret == -1)
        {
            perror("write");
            return -1;
        }
        else if(ret == 0)
        {
            break;
        }
        else
        {
            pstr += ret;
            left -= ret;
        }

    }

    return len - left;
}

size_t SocketIO::readLine(char* buf, size_t len)
{
    size_t left = len - 1;
    int ret = 0, total = 0;
    char* pstr = buf;

    while(left > 0)
    {
        ret = ::recv(_fd, pstr, left, MSG_PEEK);
        if(ret == -1 && errno == EINTR)
        {
            continue;
        }
        else if(ret == -1)
        {
            perror("recv");
            return -1;
        }
        else if(ret == 0)
        {
            break;
        }
        else 
        {
            for(int i = 0; i < ret; ++i)
            {
                if(pstr[i] == '\n')
                {
                    int sz = i + 1;
                    readn(pstr, sz);
                    pstr += sz;
                    *pstr =  '\0';
                    return total + sz;
                }
            }
        }

        readn(pstr, ret);
        pstr += ret;
        left -= ret;
        total += ret;
    }
    *pstr = '\0';
    return len - left;
}
